#'
#' @title ## 差异基因火山图
#' @TODO  利用异分析结果，并绘制火山图
#' @description 利用异分析结果，并绘制火山图
#' @details 如果`saveplot = T`，则会在路径`output_dir`下生成一个文件夹，以exp的变量名字命名，用于保存结果图片
#' @param DEG_res  一个差异分析结果，表头必须为以下格式。是全部基因的差异分析结果，未经筛选的全部结果。
#'                  列名必须包含 gene、log2FC、pvalue、adjusted_pvalue
#' @param saveplot 是否保存图片，默认参数 `F`
#' @param log2FC_value 差异筛选log2FC数值
#' @param adj.p 筛选差异基因 矫正后p值阈值
#' @param output_dir 生成图片文件目录
#' @param display_gene 火山图中展示的基因，是一个字符串向量
#' @param var_name 在生成文件夹以及命名的时候用于命名
#'
#' @return *list*
#' @export
#' @author *WYK*
#'
DEG_volcano_heatmap <- function(DEG_res = NULL, log2FC_col = NULL,adj.p_col = NULL,p_col = NULL,
                                log2FC_value = 1, saveplot = F, adj.p = 0.05, p = NULL,
                                output_dir = "/pub/users/innertech/wyk/Project_output/GAP1234/",
                                display_gene = NULL, var_name = NULL) {
  if (length(var_name) == 0) {
    var_name <- deparse(substitute(exp))
  }

  figure_list <- list()

  require(tidyverse)
  require(cowplot)

  if (!is.null(p)) {
    DEG_res <- DEG_res %>%
      select(-adjusted_pvalue) %>%
      dplyr::rename(adjusted_pvalue = pvalue)
    adj.p <- p
  }

  colnames(DEG_res)[colnames(DEG_res) == log2FC_col] <- 'log2FC'
  colnames(DEG_res)[colnames(DEG_res) == adj.p_col] <- 'adjusted_pvalue'

  degs <- DEG_res %>%
    filter(adjusted_pvalue < adj.p) %>%
    filter(log2FC > log2FC_value | log2FC < (-log2FC_value))

  Down <- degs %>%
    filter(log2FC < (-log2FC_value)) %>%
    nrow(.)

  Up <- degs %>%
    filter(log2FC > log2FC_value) %>%
    nrow(.)

  NoSig <- nrow(DEG_res) - Up - Down

  up_chr <- sprintf("Up: %s", Up)
  down_chr <- sprintf("Down: %s", Down)

  threshold <- DEG_res %>%
    mutate(threshold = case_when(
      log2FC > log2FC_value & adjusted_pvalue < adj.p ~ 'Up', # ,sprintf("Up: %s", Up)
      log2FC < -log2FC_value & adjusted_pvalue < adj.p ~ 'Down', # ,sprintf("Down: %s", Down)
      adjusted_pvalue > adj.p ~ "NoSig", # sprintf("NoSig: %s", NoSig),
      between(log2FC, -log2FC_value, log2FC_value) ~ "NoSig" # sprintf("NoSig: %s", NoSig)
    )) %>%
    select(threshold) %>%
    pull() %>%
    factor(.)

  Volcano_plot <- ggplot(data = DEG_res, aes(x = log2FC, y = -log10(adjusted_pvalue))) +
    xlab("log<sub>2</sub>Fold Change") +
    ylab("-log<sub>10</sub>adj.pvalue") +
    geom_point(size = 1, alpha = .9, aes(colour = threshold)) +
    theme_test(base_size = 15) +
    scale_color_manual(values = c(
      'Down' = "#367EB8",
      "NoSig" = "grey",
      'Up' = "#E4191C"
    )) +
    geom_hline(yintercept = -log10(adj.p), lty = 2, colour = "#242424") +
    theme(
      legend.position = "top",
      legend.title = element_blank(),
      legend.text = element_text(size = 10)
    ) +
    theme(
      axis.title.x = ggtext::element_markdown(),
      axis.title.y = ggtext::element_markdown()
    )

  if (!is.null(p)) {
    Volcano_plot <- Volcano_plot + ylab("-log<sub>10</sub>pvalue")
  }

  # if (as.numeric(log2FC_value) == 0) {
  #   Volcano_plot
  # } else {
  Volcano_plot <- Volcano_plot +
    geom_vline(xintercept = -log2FC_value, lty = 2, colour = "#242424") +
    geom_vline(xintercept = log2FC_value, lty = 2, colour = "#242424")
  # }

  # topgene <- c(Top_gene, Down_gene)

  # forheatmap_exp <- exp[topgene, ]

  if (!is.null(display_gene)) {
    # forheatmap_exp <- na.omit(exp[display_gene, ])


    display_gene <- display_gene[display_gene %in% {
      degs %>% pull(1)
    }]

    Volcano_plot <- Volcano_plot + ggrepel::geom_text_repel(
      data = DEG_res %>% filter(gene %in% display_gene),
      aes(label = gene), max.overlaps = 10
    ) + geom_point(
      data = DEG_res %>% filter(gene %in% display_gene),
      color = "black", shape = 21
    )
  }

  # p_heatmap <- tryCatch(
  #   Heatmap_manul_NoSplit_forVol(
  #     data_input = forheatmap_exp,
  #     color_used = color_used,
  #     cluster_name = cluster_name,
  #     group_infor = sample_group %>% arrange(group) %>% column_to_rownames("sample"),
  #     saveplot = F,
  #     output_dir = "./",
  #     var_name = var_name,
  #     width_used = 4.7, height_used = 6, heatmap_name = " "
  #   ),
  #   error = function(e) {
  #     return("error in heatmap")
  #   }
  # )


  # print(p)

  figure_list[[1]] <- Volcano_plot

  message(sprintf("There're %s Differential Genes. ", nrow(degs)), sprintf("%s is Down. ", Down), sprintf("%s is Up.", Up))

  figure_list[[2]] <- degs

  if (saveplot) {
    if (!dir.exists(sprintf("%s/DEGS_Vol_heatmap_%s", output_dir, var_name))) {
      dir.create(sprintf("%s/DEGS_Vol_heatmap_%s", output_dir, var_name), showWarnings = F, recursive = T)
    } else {
      print(sprintf("Dir '%s/DEGS_Vol_heatmap_%s' is existed.", output_dir, var_name))
    }

    ggsave2(
      filename = sprintf("%s/DEGS_Vol_heatmap_%s/Volcano_plot_%s.pdf", output_dir, var_name, var_name),
      plot = Volcano_plot, width = 4.43, height = 5
    )

  }

  return(figure_list)
}



suppressMessages(library(tidyverse)); suppressMessages(library(magrittr))
df = tibble(logfc = runif(100,-5,5),adjp = runif(100,0,0.1))


p = DEG_volcano_heatmap(df,'logfc','adjp',log2FC_value = 1,adj.p = 0.05)

p[[1]]
